作用域链

当代码在一个环境中执行时,会创建一个**作用域链对象(scope chain)**。

作用域链的首位,始终是当前执行环境的变量对象。这是一个包含 arguments 和其它命名参数值的活动对象。第二位是外部函数的活动对象,第三位是外部函数的外部函数的活动对象,......,直到作为作用域终点的全局执行环境。

var name = "zhar";
function say(){
  var age = 30;
  console.log(name+"-"+age+"-"+address);// 错误:address is not defined
  function info(){
    var address = "北京";
    console.log(name+"-"+age+"-"+address);//zhar-30-北京
  }
  info()
}
say();//
console.log(name+"-"+age+"-"+address);// 错误:age is not defined

这段代码共有三个执行环境:全局环境(window)、say()局部环境、info()局部环境。

在全局环境中有一个变量 name 和一个函数say,在say中有一个变量age和一个函数info,在info中有一个变量address。通过报错信息可以看到,say中可以访问到当前环境中的age及全局环境中的name,info可以访问到当前环境中的address、say环境中的age、全局环境中的name,而在window环境中则只可以访问到name。

可以得出:内部环境可以通过作用域链访问到所有的外部环境,但外部环境不能访问内部环境中的任何变量或函数。

作用域链是有层级、线性的;

*JS 在查找变量时,在当前环境查找到变量便停止继续向上搜索*

var name = 'zhar';
function say(){
  var name = 'tom';
  console.log(name);//tom
}
say();
console.log(name);//zhar

作用域链示意图:

没有块级作用域

在 JS 中并没有像强类型语言中的块级作用域,比如在JAVA中一对花括号中,是一个块级的作用域

var name = 'zhar'
if(true){
  var name = 'tom';
}
console.log(name);

//按着上面作用域链中描述的情况,name应该输出为zhar,但实际情况为tom,便是因为在JS中没有块级作用域的概念

//另外一种块级作用域的典型情况为for循环

for(var i=0;i<5;i++){
  //dosomething
}
console.log(i);//5
```

results matching ""

    No results matching ""